// vue3 响应式原理： 利用Proxy对象对数据拦截
function isObj(obj){
    return typeof obj ==='object'
}
// 
const toProxy = new WeakMap()  //obj: observe   // 缓存对象
const toRaw = new WeakMap() // observe:obj  // 缓存代理后的对象

function reactive(obj){
    if(!isObj(obj)){return obj}
// 查找传入的对象是否已经代理过，  有则直接返回这个代理过后的代理对象
    if(toProxy.has(obj)){
        return toProxy.get(obj)
    }
    // 传入的就是代理对象，则直接返回，不用反复代理
    if(toRaw.has(obj)){
        return obj
    }
    const observe = new Proxy(obj,{
        get(target,key,receiver){
            // 访问
            const res = Reflect.get(target,key,receiver)
            console.log(`获取${key}:${res}`)
            // 运行时的嵌套递归
            return  isObj(res)?reactive(obj):res
        },
        set(target,key,value,receiver){
            const res = Reflect.set(target,key,value,receiver)
            console.log(`设置${key}：${value}`)
            return res 
        },
        deleteProperty(target,key){
            const res = Reflect.deleteProperty(target,key)
            console.log(`删除${key}`)
            return res 
        }
    })

    // 缓存
    toProxy.set(obj,observe)
    toRaw.set(observe,obj)
    return observe
}

const data  = {foo:"fooooo",bar:{a:1}}
const react = reactive(data)

// 1. 获取
// react.foo
// 2.  设置已存在的属性
// react.foo = "fooooooo"
// 3. 设置不存在的属性
// react.baz = "bazzz"
// 4. 设置嵌套对象
// react.bar.a = 10



// 避免重复代理的问题  
//  
 console.log(reactive(data)===react
 )